
// #include "player_audio_sink.h"
// #include "decoder.h"
// #include "format_type.h"

// #include "hal_display.h"
#include "codec_interface.h"

#include <algorithm>
#include <cstring>
#include <fstream>
#include <iostream>
#include <sstream>

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>

using OHOS::Surface;

using namespace std;
using namespace OHOS;
using namespace OHOS::Media;

#define BUFF_SIZE 1024

int main(int argc, char **argv)
{
    int ret;

    int fd = open(argv[1], O_RDONLY);
    printf("----->> open(%d): %s \n", fd, argv[1]);

    /////////////////////////////

    // ret = HalPlayerSysInit();
    // printf("----->> HalPlayerSysInit(%d) \n", ret);

    ret = CodecInit();
    printf("----->> CodecInit(%d) \n", ret);

    const char *audioEncName = "codec.aac.hardware.decoder";
    CodecType attr_val = AUDIO_DECODER;
    Param attr;
    attr.key = KEY_CODEC_TYPE;
    attr.val = &attr_val;
    attr.size = sizeof(uint32_t);
    ret = CodecCreate(audioEncName, &attr, 1, NULL);
    printf("----->> CodecCreate(%d) \n", ret);

    sleep(1);

    ret = CodecDeinit();
    printf("----->> CodecDeinit(%d) \n", ret);

#if 0
    /////////////////////////////

    std::shared_ptr<AudioSink> audioSink = std::make_shared<AudioSink>();
    std::shared_ptr<Decoder> decoder = std::make_shared<Decoder>();

    /////////////////////////////

    SinkAttr sAttr;
    sAttr.sinkType = SINK_TYPE_AUDIO;
    sAttr.trackId = 0;
    sAttr.audAttr.format = CODEC_AAC; // CodecFormat
    sAttr.audAttr.sampleFmt = 2;
    sAttr.audAttr.sampleRate = 32000;
    sAttr.audAttr.channel = 2;
    sAttr.audAttr.volume = 6;

    ret = audioSink->Init(sAttr);
    printf("----->> audioSink->Init(%d) \n", ret);

    ret = audioSink->Start();
    printf("----->> audioSink->Start(%d) \n", ret);

    /////////////////////////////

    AvAttribute aAttr;
    aAttr.type = AUDIO_DECODER;
    aAttr.adecAttr.mime = MEDIA_MIMETYPE_AUDIO_AAC;
    aAttr.adecAttr.priv = nullptr;
    aAttr.adecAttr.bufSize = 1024;
    const std::string audioName = "codec.aac.soft.decoder";
    ret = decoder->CreateHandle(audioName, aAttr);
    printf("----->> decoder->CreateHandle(%d) \n", ret);

    ret = decoder->StartDec();
    printf("----->> decoder->StartDec(%d) \n", ret);

    /////////////////////////////

    uint8_t buff[BUFF_SIZE];
    CodecBufferInfo codeBuffInfo;
    codeBuffInfo.type = BUFFER_TYPE_VIRTUAL;
    codeBuffInfo.addr = buff;
    codeBuffInfo.offset = 0;
    codeBuffInfo.length = sizeof(buff);
    codeBuffInfo.size = sizeof(buff);

    InputInfo inInfo;
    OutputInfo outInfo;
    OutputInfo outInfo2;

    int timeout = 0;
    while(timeout++ < 100)
    {
        codeBuffInfo.length = read(fd, buff, sizeof(buff));
        if (codeBuffInfo.length < 1)
        {
            printf("----->> read(%d) \n", codeBuffInfo.length);
            break;
        }

        memset_s(&inInfo, sizeof(inInfo), 0, sizeof(InputInfo));
        ret = decoder->DequeInputBuffer(inInfo, 100);
        if (ret != 0)
        {
            printf("----->> decoder->DequeInputBuffer(%d) \n", ret);
            continue;
        }

        inInfo.bufferCnt = 1;
        inInfo.buffers = &codeBuffInfo;
        inInfo.pts = 0;
        inInfo.flag = 0;

        ret = decoder->QueueInputBuffer(inInfo, 100);
        printf("----->> decoder->QueueInputBuffer(%d) \n", ret);

        memset_s(&outInfo, sizeof(outInfo), 0, sizeof(OutputInfo));
        ret = decoder->DequeueOutputBuffer(outInfo, 100);
        printf("----->> decoder->DequeueOutputBuffer(%d) \n", ret);
        if (ret != 0) {
            outInfo.bufferCnt = 0;
            outInfo.type = AUDIO_DECODER;
            outInfo.vendorPrivate = nullptr;
            outInfo.buffers = nullptr;
        }

        ret = audioSink->RenderFrame(outInfo);
        printf("----->> audioSink->RenderFrame(%d) \n", ret);

        memset_s(&outInfo2, sizeof(outInfo2), 0, sizeof(OutputInfo));
        ret = audioSink->DequeReleaseFrame(outInfo2);
        printf("----->> audioSink->DequeReleaseFrame(%d) \n", ret);

        if (ret == 0)
        {
            ret = decoder->QueueOutputBuffer(outInfo2, 100);
            printf("----->> decoder->QueueOutputBuffer(%d) \n", ret);
        }

        usleep(10000);
    }

    ret = audioSink->Stop();
    printf("----->> audioSink->Stop(%d) \n", ret);

    ret = decoder->DestroyHandle();
    printf("----->> decoder->DestroyHandle(%d) \n", ret);

#endif

    return 0;
}
